package com.tgy.admin.Service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.tgy.admin.Service.AdminService;
import com.tgy.admin.Service.MenuService;
import com.tgy.admin.util.BeanFieldUtils;
import com.tgy.constant.RedisKey;
import com.tgy.core.service.SysAdminRoleService;
import com.tgy.core.service.SysAdminService;
import com.tgy.core.service.SysRoleService;
import com.tgy.enums.ResponseStatusEnum;
import com.tgy.enums.YesOrNo;
import com.tgy.exception.GlobalException;
import com.tgy.exception.ResultException;
import com.tgy.page.PageQuery;
import com.tgy.pojo.SysAdmin;
import com.tgy.pojo.SysAdminRole;
import com.tgy.pojo.SysRole;
import com.tgy.result.GraceJSONResult;
import com.tgy.result.LayuiTableResult;
import com.tgy.util.RedisUtils;
import com.tgy.vo.SysRoleVo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author tianguiyin
 * @version 1.0
 * @date 2022/6/21 21:04
 *
 * 后台用户业务实现
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Resource
    private SysAdminService sysAdminService;
    @Resource
    private SysAdminRoleService sysAdminRoleService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private BeanFieldUtils beanFieldUtils;
    @Resource
    private RedisUtils redis;
    @Resource
    private MenuService menuService;

    /**
     *  默认超级管理员用户ID，与数据库保持一致
     */
    @Value("${tgy.adminId}")
    private String adminId;

    @Override
    public LayuiTableResult getAdminList(SysAdmin bo,PageQuery pageQuery) {
        // bo.setStatus(-1);
        return sysAdminService.queryLayuiPageList(bo,pageQuery);
    }

    @Override
    public GraceJSONResult updateStatus(String id, Integer status) {
        int i = sysAdminService.updateStatus(id,status);
        if (i>0){
            return GraceJSONResult.ok();
        }else {
            return GraceJSONResult.error();
        }
    }

    @Override
    public GraceJSONResult addSysAdmin(SysAdmin sysAdmin) {
        try {
            beanFieldUtils.add(sysAdmin);
            sysAdmin.setPassword(BCrypt.hashpw(sysAdmin.getPassword()));
            Boolean aBoolean = sysAdminService.insertByBo(sysAdmin);
            return GraceJSONResult.ok(ResponseStatusEnum.ADD_SUCCESS);
        }catch (Exception e){
            if (e instanceof ResultException){
                ResultException e1 = (ResultException) e;
                return e1.getGraceJSONResult();
            }else {
                e.printStackTrace();
                return GraceJSONResult.error(ResponseStatusEnum.ADD_ERROR);
            }
        }
    }

    @Override
    public GraceJSONResult updateSysAdmin(SysAdmin sysAdmin) {
        try {
            SysAdmin sysAdmin1 = sysAdminService.queryById(sysAdmin.getId());
            // String createdBy = sysAdmin1.getCreatedBy();
            // LocalDateTime createdTime = sysAdmin1.getCreatedTime();
            if (!sysAdmin.getPassword().equals(sysAdmin1.getPassword())){
                sysAdmin.setPassword(BCrypt.hashpw(sysAdmin.getPassword()));
            }
            BeanUtil.copyProperties(sysAdmin,sysAdmin1);
            beanFieldUtils.update(sysAdmin1);
            // sysAdmin1.setCreatedBy(createdBy);
            // sysAdmin1.setCreatedTime(createdTime);
            Boolean aBoolean = sysAdminService.updateByBo(sysAdmin1);
            return GraceJSONResult.ok(ResponseStatusEnum.UPDATE_SUCESS);
        }catch (Exception e){
            if (e instanceof ResultException){
                ResultException e1 = (ResultException) e;
                return e1.getGraceJSONResult();
            }else {
                e.printStackTrace();
                return GraceJSONResult.error(ResponseStatusEnum.UPDATE_ERROR);
            }
        }
    }

    @Transactional
    @Override
    public GraceJSONResult delSysAdmin(String id) {
        try {
            if (id.equals(adminId)){
                GlobalException.display(ResponseStatusEnum.ACCOUNT_NOT_DEL);
            }
            sysAdminService.deleteById(id);
            // 删除用户角色表中的关联数据
            List<String> list = new ArrayList<>();
            list.add(id);
            sysAdminRoleService.deleteByAid(list);
            return GraceJSONResult.ok(ResponseStatusEnum.DDELETE_SUCESS);
        }catch (Exception e){
            e.printStackTrace();
            return GraceJSONResult.error(ResponseStatusEnum.DDELETE_ERROR);
        }
    }

    @Transactional
    @Override
    public GraceJSONResult delSysAdminIds(List<String> ids) {
        try {
            ids.remove(adminId);
            sysAdminService.deleteWithValidByIds(ids,false);
            // 删除用户角色表中的关联数据
            sysAdminRoleService.deleteByAid(ids);
            return GraceJSONResult.ok(ResponseStatusEnum.DDELETE_SUCESS);
        }catch (Exception e){
            e.printStackTrace();
            return GraceJSONResult.error(ResponseStatusEnum.DDELETE_ERROR);
        }
    }

    @Override
    public GraceJSONResult getSysAdminById(String id) {
        return GraceJSONResult.ok(sysAdminService.queryById(id));
    }

    @Override
    public LayuiTableResult getAllSysRoleList(String userId,PageQuery pageQuery) {
        if (StrUtil.isBlank(userId)){
            GlobalException.display(GraceJSONResult.error("id为空"));
        }
        SysRole bo = new SysRole();
        bo.setAvailable(YesOrNo.YES.type);
        LayuiTableResult layuiTableResult = sysRoleService.queryLayuiPageList(bo, pageQuery);
        List<SysRoleVo> list = new ArrayList<>();
        List<SysRole> data = (List<SysRole>)layuiTableResult.getData();
        // 获取当前人的角色信息
        String s = redis.get(RedisKey.LOGIN_USER_ROLE + ":" + userId);
        if (StrUtil.isBlank(s)){
            menuService.getMenuAndRoleAndPermission(userId);
        }
        List<SysRole> roles = JSONObject.parseArray(redis.get(RedisKey.LOGIN_USER_ROLE+":"+userId),SysRole.class);
        List<String> collect = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roles)){
            collect = roles.stream().map(SysRole::getId).collect(Collectors.toList());
        }
        for (SysRole role : data) {
            SysRoleVo vo = new SysRoleVo();
            BeanUtil.copyProperties(role,vo);
            if (collect.contains(role.getId())){
                vo.setLAY_CHECKED(true);
                vo.setChecked(true);
            }
            list.add(vo);
        }
        layuiTableResult.setData(list);

        // 更新权限相关信息
        new Thread(){
            @Override
            public void run() {
                menuService.getMenuAndRoleAndPermission(userId);
            }
        }.start();

        return layuiTableResult;
    }

    @Transactional
    @Override
    public GraceJSONResult addRole(String aid, String rids) {
        if (StrUtil.isBlank(aid)){
            GlobalException.display(GraceJSONResult.error("用户ID不能为空"));
        }
        // 清空之前用户的角色信息
        List<String> aids = new ArrayList<>();
        aids.add(aid);
        sysAdminRoleService.deleteByAid(aids);

        //添加新的信息
        List<String> list = new ArrayList<>(Arrays.asList(rids.split(",")));
        List<SysAdminRole> adminRoles = new ArrayList<>();
        for (String rid : list) {
            SysAdminRole adminRole = new SysAdminRole();
            adminRole.setAid(aid);
            adminRole.setRid(rid);
            adminRoles.add(adminRole);
        }
        sysAdminRoleService.insertByList(adminRoles);

        String loginId = StpUtil.getLoginId().toString();
        // 更新权限相关信息
        new Thread(){
            @Override
            public void run() {
                menuService.getMenuAndRoleAndPermission(loginId);
            }
        }.start();
        return GraceJSONResult.ok();
    }
}
